home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Libraries / grayimage / read_def.cc < prev    next >
Encoding:
Text File  |  1994-06-30  |  13.9 KB  |  328 lines  |  [TEXT/R*ch]

  1. short("Reading mode/submode");
  2.   if( checksum_present )
  3.     checksum += word;
  4.   *(DEFTag *)&field = word;
  5.  
  6.   assert( field.data_size >= 0 );
  7.   assert( field.data_size < sizeof(field.data) );
  8.  
  9.   if( !fs.read((char *)field.data,field.data_size) )
  10.     _error("Dying because of I/O error above",
  11.        (perror("Field data read error"),0));
  12.  
  13.   if( checksum_present )
  14.   {
  15.     register Word * dp;
  16.     for(dp=field.data; dp < field.data + length_words;)
  17.       checksum += (unsigned short)*dp++;
  18.     checksum += fs.read_short("reading the checksum");
  19.     assert( checksum == 0 );
  20.   }
  21.  
  22.   return fs;
  23. }
  24.  
  25.  
  26.                 // Standard Field header, from which
  27.                 // particular product field inherit
  28. class StdField : public DEFTag
  29. {
  30. public:
  31.   const enum Length_type { Exact_length, Min_length };
  32. private:
  33.   const int length_words;        // Length of the field in words
  34.   Length_type length_type;
  35.   char data[0];                // Data follow
  36. protected:
  37.   StdField(const DEFTag tag, const int _length, const Length_type _ltype)
  38.     : DEFTag(tag), length_words(_length), length_type(_ltype) {}
  39.   ~StdField(void) {}
  40.   void operator = (const Field& field);
  41. };
  42.  
  43.                 // Assignment of a field
  44. void StdField::operator = (const Field& field)
  45. {
  46.   assert( *(DEFTag *)this == field );    // Make sure the field assigned is 
  47.                     // really of the type we expect
  48.   if( length_type == Exact_length )
  49.     assert( sizeof(Word) * length_words == field.length() );
  50.   else
  51.     assert( sizeof(Word) * length_words <= field.length() );
  52.   memcpy(data,field.data,field.length());
  53. }
  54.  
  55. /*
  56.  *------------------------------------------------------------------------
  57.  *              Specific blocks for SAT products
  58.  * Constructor assignes default values to be used if the field isn't
  59.  * specified in the input stream
  60.  */
  61.  
  62. class ProductIDField : public StdField
  63. {
  64.                 // Contents of the data field
  65.   char originator[4];            // Facility that has generated product
  66.   char classification;            // secrecy stuff
  67.   char retention_time;            // in days, -1 or 0 means dummy
  68.   char file_indicator;            // Code of the originating agency
  69.   char catalog_no[4];
  70.   char time_generated[3];        // e.g., in hrs
  71.   char misc_id[2];            // See App. C, Table C2-1
  72.                     // Time the file was generated 
  73.   Word year;                // full century year, in binary
  74.   char month, day, hour, minute;
  75.  
  76. public:
  77.   ProductIDField(const Field& field);
  78.   ~ProductIDField(void) {}
  79.   operator const char * (void) const;    // Give a readable description
  80. };
  81.  
  82.                 // Assign from a generic field
  83. ProductIDField::ProductIDField(const Field& field)
  84.     : StdField(DEFTag(1,1),11,StdField::Exact_length)
  85. {
  86.   *(StdField *)this = field;
  87. }
  88.  
  89.                 // Give a readable description of the Product
  90.                 // ID. Returns a ptr to a STATIC string
  91. ProductIDField::operator const char * (void) const
  92. {
  93.   static char buffer[700];
  94.   sprintf(buffer,"Originator %.4s, classification %c, retention_time %d\n"
  95.       "file_indicator %0o, catalog_number %.4s, time_generated %.3s\n"
  96.       "misc id %.2s, date %d/%d/%d %02d:%02d\n",
  97.       originator,classification, 
  98.       (retention_time == -1 ? 0 : retention_time),
  99.       file_indicator,catalog_no,time_generated,misc_id,
  100.       month,day,(unsigned short)year,hour,minute);
  101.   return buffer;
  102. }
  103.  
  104.                 // Classification Block
  105. class ClassifField : public StdField
  106. {
  107.   char title[100];
  108. public:
  109.   ClassifField(void)  
  110.     : StdField(DEFTag(1,3),0,StdField::Min_length) { title[0] = '\0'; }
  111.   ~ClassifField(void) {}
  112.   void operator = (const Field& field);
  113.   void print(void) const;
  114. };
  115.  
  116. void ClassifField::operator = (const Field& field)
  117. {
  118.   *(StdField *)this = field;
  119.   assert( field.length() < sizeof(title)-1 );
  120.   title[field.length()] = '\0';
  121. }
  122.  
  123. void ClassifField::print(void) const
  124. {
  125.   message("Classification %s\n",title);
  126. }
  127.  
  128.                 // Field describing bit sizes of other
  129.                 // field and their relative layouts
  130. class DFWidthField : public StdField 
  131. {
  132.   char field_width           : 7;
  133.   char cross_byte_boundaries   : 1;
  134.   char data_width           : 7;    // bits for the actual data
  135.   char left_justified           : 1;
  136.   DEFTag apply_to;            // Mode/submode for which applicable
  137.  
  138. public:
  139.   DFWidthField(void)
  140.     : StdField(DEFTag(1,5),2,StdField::Exact_length), apply_to(DEFTag(6,1))
  141.     { cross_byte_boundaries = left_justified = 0;
  142.       field_width = data_width = 8;
  143.     }
  144.   ~DFWidthField(void) {}
  145.   void operator = (const Field& field);
  146.   void print(void) const;
  147. };
  148.  
  149. void DFWidthField::operator = (const Field& field)
  150. {
  151.   *(StdField *)this = field;
  152.   assert( field_width <= 16 && field_width > 0 );
  153.   assert( data_width <= field_width && data_width > 0 );
  154. }
  155.  
  156. void DFWidthField::print(void) const
  157. {
  158.   message("%d data bits within %d-bit field %s byte/word boundaries\n",
  159.       data_width,field_width,
  160.       cross_byte_boundaries ? "crossing" : "within");
  161.   message("%s, applied to tag %s\n",
  162.       left_justified ? "left_justified" : "contiguos",
  163.       (const char *)apply_to);
  164. }
  165.  
  166.  
  167.  
  168.                 // Satellite Product Definition Block
  169. class SATDefField : public StdField
  170. {
  171. public:
  172.   char pi_set;            // Background projection on which SAT is valid
  173.   char gi_set;            // Grid indicator for which the data is valid
  174.   char sat_id[2];
  175.   Word longit_X;        // Longitude X for the base of the product
  176.   char resolution_code;        // in 10s of nautical miles
  177.   char sat_type;        // 0 - visual, 1 - IR, mixed otherwise
  178.   Word x_max;            // no. of pixels across
  179.   Word y_max;            // no. of pixels in height
  180.   unsigned char enhance_max;    // Needed if pixel enhancement is used
  181.   unsigned char enhance_min;    // (limits of the gray-scale look-up referenced
  182.   char enhance_id;        // by the enhance_id)     
  183.   unsigned char arc_length;    // Length of each scanline in tens of minutes
  184.                 // of arc
  185.   char x_center, y_center;    // Center of the product in units of the grid
  186.   Word latitude;        // LAT and LON of the center of the product in
  187.   Word longitude;        // hundredths of degree
  188.   unsigned char title_len;
  189.   char title[256];
  190.   
  191. public:
  192.   SATDefField(const Field& field);
  193.   ~SATDefField(void) {}
  194.   void print(void) const;
  195. };
  196.  
  197. SATDefField::SATDefField(const Field& field)
  198.     : StdField(DEFTag(6,020),13,StdField::Min_length)
  199. {
  200.   *(StdField *)this = field;
  201.   title[title_len] = '\0';
  202. }
  203.  
  204.  
  205. void SATDefField::print(void) const
  206. {
  207.   message("\nSAT image '%s' id %.2s type %d\n",title,sat_id,sat_type);
  208.   message("%dx%d pixels, enhancement code %d, for pixel interval %d-%d\n",
  209.       (unsigned short)x_max,(unsigned short)y_max, enhance_id,
  210.       enhance_min,enhance_max);
  211.   message("Background projection %d, grid %d, base longitude %d\n",
  212.       pi_set,gi_set, (short)longit_X);
  213.   message("scanline resolution %f nautical miles, or %d' of grid\n",
  214.       resolution_code/10.,10*arc_length);
  215.   message("Image center is at (%d,%d) on the grid, or %2.2f LAT %2.2f LONG\n",
  216.       x_center,y_center,((short)latitude)/100.,((short)longitude)/100.);
  217. }
  218.  
  219.                 // Pixel product definition block
  220. class PixelDefField : public StdField 
  221. {
  222.   char pi_set;        // Define the background projection for the product
  223.   char matrix_code;    // Code for standard SAT dimensions
  224.   char scan_code;    // Raster scan directions (1 - from top to bottom)
  225.   char pack_code;    // Pixel pack code
  226.  
  227. public:
  228.   PixelDefField(void)
  229.     : StdField(DEFTag(6,030),2,StdField::Exact_length)
  230.     { pi_set = 0; matrix_code = -1; scan_code = 1; pack_code = 0; }
  231.   ~PixelDefField(void) {}
  232.   void operator = (const Field& field);
  233.   void print(void) const;
  234. };
  235.  
  236. void PixelDefField::operator = (const Field& field)
  237. {
  238.   *(StdField *)this = field;
  239.   assert( matrix_code < 64 );
  240.   assert( scan_code > 0 && scan_code <= 2 );
  241. }
  242.  
  243. void PixelDefField::print(void) const
  244. {
  245.   message("\nbackground grid id %d, pixel matrix code %d\n",
  246.       pi_set,matrix_code);
  247.   message("scanlines go %s packed with method labelled %d\n",
  248.       scan_code == 1 ? "top to bottom" : "bottom to top",
  249.       pack_code);
  250. }
  251.  
  252.  
  253.                 // Pixel product definition block
  254. class RasterScanField : public StdField 
  255. {
  256. public:
  257.   Word xrow, ycol;    // Coordinates of the beginning of a scanline
  258.   Word no_pixels;    // in this raster line
  259.   unsigned char pixels [4096];    // Pixels themselves
  260.  
  261. public:
  262.   RasterScanField(void)
  263.     : StdField(DEFTag(6,1),3,StdField::Min_length)
  264.     { *(short *)&xrow = 0; *(short *)&ycol = 0; *(short *)&no_pixels = 0; }
  265.   ~RasterScanField(void) {}
  266.   void operator = (const Field& field);
  267. };
  268.  
  269.  
  270. void RasterScanField::operator = (const Field& field)
  271. {
  272.   *(StdField *)this = field;
  273. }
  274.  
  275.  
  276.  
  277. main(void)
  278. {
  279.   EndianIO fs("/projects/r2d2/oleg/IMAGES/packed.700",ios::in);
  280.   fs.set_bigendian();
  281.   Field field;
  282.  
  283.   fs >> field;
  284.   ProductIDField pid(field);
  285.   message((const char *)pid);
  286.  
  287.   fs >> field;
  288.   SATDefField sat_def(field);
  289.   sat_def.print();
  290.  
  291.   RasterScanField scanline;
  292.  
  293.   PixelDefField pixel_def;    // Other fields that might show up
  294.   ClassifField secrecy_fld;
  295.   DFWidthField width_def;
  296.  
  297.   for(fs >> field; !(field == scanline); fs >> field)
  298.   {
  299.     if( field == pixel_def )
  300.       pixel_def = field, pixel_def.print();
  301.     else if( field == secrecy_fld )
  302.       secrecy_fld = field, secrecy_fld.print();
  303.     else if( field == width_def )
  304.       width_def = field, width_def.print();
  305.     else
  306.       _error("Unexpected tag %s",(const char *)*(DEFTag *)&field);
  307.   }
  308.  
  309.                 // Check out that we can handle that image
  310.  
  311.   IMAGE image((unsigned short)sat_def.y_max,
  312.           (unsigned short)sat_def.x_max,8);
  313.  
  314.   for(; !(field == DEFTag(1,2)); fs >> field)
  315.   {
  316.     scanline = field;
  317.     register int i;
  318. //    message("xrow %d, ycol %d, %d pixels\n",(unsigned short)scanline.xrow,
  319. //        (unsigned short)scanline.ycol,(unsigned short)scanline.no_pixels);
  320.     for(i=0; i<(unsigned short)scanline.no_pixels; i++)
  321.       image((unsigned short)scanline.xrow,(unsigned short)scanline.ycol+i)
  322.     = scanline.pixels[i];
  323.   }
  324.   image.display("image");
  325. }
  326.  
  327.  
  328.